#pragma once
#include <queue>
#include <pthread.h>
#include <string>
#include <iostream>
#include <unistd.h>

#define CAPACITY 10
template <class T>
class taskQueue
{
public:
    taskQueue(const int &capacity = CAPACITY)
        : _capacity(capacity)
    {
        pthread_cond_init(&_producer, nullptr);
        pthread_cond_init(&_consumer, nullptr);
        pthread_mutex_init(&_mutex, nullptr);
    }
    ~taskQueue()
    {
        pthread_mutex_destroy(&_mutex);
        pthread_cond_destroy(&_producer);
        pthread_cond_destroy(&_consumer);
    }
    void take_top(T &top) // 消费者拿资源
    {
        pthread_mutex_lock(&_mutex);

        while (_task.empty())
        {
            pthread_cond_wait(&_consumer, &_mutex);
        }
        top = _task.front();
        _task.pop();
        pthread_cond_signal(&_producer);
        pthread_mutex_unlock(&_mutex);
    }
    void push(const T &newTask) // 生产者生产资源
    {
        pthread_mutex_lock(&_mutex);

        while (isFull())
        {
            pthread_cond_wait(&_producer, &_mutex);
        }

        _task.push(newTask);
        pthread_cond_signal(&_consumer);
        pthread_mutex_unlock(&_mutex);
    }
    bool isFull()
    {
        return _capacity == _task.size();
    }

private:
    std::queue<T> _task;
    int _capacity;
    pthread_cond_t _producer; // 生产者条件变量 -》空间资源
    pthread_cond_t _consumer; // 消费者条件变量 -》任务资源
    pthread_mutex_t _mutex;
};
